package com.kwan80gmail.flextime.activities;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.kwan80gmail.flextime.R;
import com.kwan80gmail.flextime.controllers.MainController;
import com.kwan80gmail.flextime.models.GeofenceStore;
import com.kwan80gmail.flextime.models.GpsTracker;
import com.kwan80gmail.flextime.models.Place;
import com.kwan80gmail.flextime.models.SqlLiteHelper;

import android.graphics.Color;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

import java.util.ArrayList;


public class MapsActivity extends FragmentActivity implements OnCameraChangeListener
{

    private GoogleMap mMap; // Might be null if Google Play services APK is not available.
    /**
     * Geofence Data
     */

    /**
     * Geofences Array
     */
    ArrayList<Geofence> mGeofences;


    /**
     * Geofence Store
     */
    private GeofenceStore mGeofenceStore;
    ArrayList<Place> places = new ArrayList<>();


    private MainController controller = new MainController();
    private GpsTracker gpsTracker;
    private SqlLiteHelper database;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);


        // Initializing variables
        database = controller.getDatabase(this);
        mGeofences = new ArrayList<>();



        for (int i = 0; i < database.getPlaces().size(); i++)
        {
            mGeofences.add(createGeoFence(database.getPlaces().get(i).getName(), database.getPlaces().get(i).getLatitude()
                    , database.getPlaces().get(i).getLongitude(), database.getPlaces().get(i).getRadius()));
        }

        // Add the geofences to the GeofenceStore object.
        mGeofenceStore = new GeofenceStore(this, mGeofences);

    }

    private Geofence createGeoFence(String locationName, double latitude, double longitude, int radius)
    {
        Geofence builder = new Geofence.Builder()
                .setRequestId(locationName)
                        // The coordinates of the center of the geofence and the radius in meters.
                .setCircularRegion(latitude, longitude, radius)
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                        // Required when we use the transition type of GEOFENCE_TRANSITION_DWELL
                .setLoiteringDelay(30000)
                .setTransitionTypes(
                        Geofence.GEOFENCE_TRANSITION_ENTER
                                | Geofence.GEOFENCE_TRANSITION_DWELL
                                | Geofence.GEOFENCE_TRANSITION_EXIT).build();

        return builder;
    }

    @Override
    protected void onStart()
    {
        super.onStart();
    }

    @Override
    protected void onStop()
    {
        Log.v("GeoFence", "Disconnected");
        super.onStop();
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS)
        {
            setUpMapIfNeeded();
        } else
        {
            GooglePlayServicesUtil.getErrorDialog(
                    GooglePlayServicesUtil.isGooglePlayServicesAvailable(this),
                    this, 0);
        }
    }


    /**
     * Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
     * installed) and the map has not already been instantiated.. This will ensure that we only ever
     * call {@link #setUpMap()} once when {@link #mMap} is not null.
     * <p/>
     * If it isn't installed {@link SupportMapFragment} (and
     * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
     * install/update the Google Play services APK on their device.
     * <p/>
     * A user can return to this FragmentActivity after following the prompt and correctly
     * installing/updating/enabling the Google Play services. Since the FragmentActivity may not
     * have been completely destroyed during this process (it is likely that it would only be
     * stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
     * method in {@link #onResume()} to guarantee that it will be called.
     */
    private void setUpMapIfNeeded()
    {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null)
        {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();

            // Check if we were successful in obtaining the map.
            if (mMap != null)
            {
                setUpMap();
            }
        }
    }

    /**
     * This is where we can add markers or lines, add listeners or move the camera. In this case, we
     * just add a marker near Africa.
     * <p/>
     * This should only be called once and when we are sure that {@link #mMap} is not null.
     */
    private void setUpMap()
    {

        gpsTracker = controller.getGpsTracker(MapsActivity.this);
        // Centers the camera over the building and zooms int far enough to
        // show the floor picker.
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
                gpsTracker.getLatitude(), gpsTracker.getLongitude()), 14));


        // Hide labels.
        mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        mMap.setIndoorEnabled(false);
        mMap.setMyLocationEnabled(true);

        mMap.setOnCameraChangeListener(this);
    }

    @Override
    public void onCameraChange(CameraPosition position)
    {

        // Makes sure the visuals remain when zoom changes.
        for (int i = 0; i < database.getPlaces().size(); i++)
        {
            mMap.addCircle(new CircleOptions().center(new LatLng(database.getPlaces().get(i).getLatitude(), database.getPlaces().get(i).getLongitude()))
                    .radius(database.getPlaces().get(i).getRadius())
                    .fillColor(Color.parseColor("#FF4081"))
                    .strokeColor(Color.TRANSPARENT).strokeWidth(2));
        }
    }
}
